# koroFileHeader at Yungoal acer
# Create: 2021-06-24 10:55:46
# LastEdit: 2021-07-06 13:37:23
"""Run Command
单台主机测试脚本
"""
__author__ = '749B'

import os, sys
BASE_DIR = os.getcwd()
sys.path.append(BASE_DIR)

import argparse
import pprint
import textwrap
import msrestazure.azure_cloud
# pylint: disable = import-error
from azure_client import Azure_Client
from azure_client.models import runcmd_parse_output
from utils.blueking import job_start, job_success, job_fail
from utils.env import init_environs

from typing import Optional, List, Mapping


def init_argparse(args: Optional[List[str]] = None) -> argparse.Namespace:
    """初始化：命令行参数"""
    parser = argparse.ArgumentParser(description='Run command 运行命令')

    parser.add_argument('-e', '--envfile', help="存有用户认证信息的env文件的文件名")
    parser.add_argument('-s', '--subscription', required=True, help='限定订阅，订阅名称或订阅ID都可')
    parser.add_argument('-g', '--resource_group', required=True, help='限定资源组名称')
    parser.add_argument('-n', '--vmname', required=True, help='虚拟机的name')
    parser.add_argument('--report', action='store_true', dest='dev_report', help='调试的时候，打开。避免程序长时间没有响应')
    parser.add_argument('-w', '--wait', type=int, default=15, help='执行后，会先等待一段时间再取结果')
    parser.add_argument('-t', '--timeout', type=int, default=300, help='超时时限')

    os_type_group = parser.add_argument_group('Os Type', '全真或全假都是默认linux')
    os_type_group.add_argument('--is_linux', action='store_true', help='操作系统是linux')
    os_type_group.add_argument('--is_windows', action='store_true', help='操作系统是windows')
    
    args = parser.parse_args(args)
    return args   

def main(
    args: Optional[List[str]] = None, 
    script: Optional[List[str]] = None,
    parameters: Optional[List[Mapping[str, str]]] = None,
    ) -> None:
    """主函数"""
    # 初始化命令行参数
    if args is None:
        # 蓝鲸作业平台有BUG，重做的任务，空着的参数里都会被填充null
        args = [arg for arg in sys.argv[1:] if arg != 'null' and not arg.endswith('=null')]
    args = init_argparse(args)
    if not args.envfile:
        return job_fail("请提供存有用户认证信息的env文件的文件名")
        
    # 初始化环境变量
    envs = init_environs(args.envfile)
    if not envs:
        return job_fail("env文件解密错误")
    if envs['runtime_env'] == 'blueking':
        for key in args.__dict__.keys():
            if key.startswith('dev_'):
                v = getattr(args, key)
                if v:
                    print(f'{key}={v}: 不支持的命令行参数，已经忽略。', file=sys.stderr)
                    setattr(args, key, None)
                    
    # 实例化客户端
    CLOUD = getattr(msrestazure.azure_cloud, envs['cloud_name'])
    client = Azure_Client(CLOUD)

    if args.subscription:
        # pylint: disable = no-member
        subscription = client.get_subscriptionid_by_name(args.subscription)
        if not subscription:
            return job_fail("订阅或订阅ID不存在:%s" % args.subscription)
        args.subscription = subscription

    script = script if script is not None else SCRIPT
    parameters = parameters if parameters is not None else PARAMETERS
    is_linux = not (not args.is_linux and args.is_windows)
    # pylint: disable = no-member
    res = client.runcmd_onestep(
        args.subscription, args.resource_group, args.vmname, script,
        parameters=parameters,
        is_linux=is_linux, 
        report=args.dev_report,
        wait=args.wait,
    )
    if res[0]:
        # 命令执行完成
        res_obj = res[1].json()
        pprint.pp(res_obj)
        output = res_obj['properties']['output']['value']
        std_out, std_err = runcmd_parse_output(output)
        print("StdOut:")
        print(std_out)
        print("StdErr")
        print(std_err)
    else:
        # 命令未执行完成
        pprint.pp(res[1].json())

SCRIPT = textwrap.dedent("""\
    date
    """).splitlines()
    
PARAMETERS = None

if __name__ == '__main__':

    job_start()

    ###### 可在此处开始编写您的脚本逻辑代码
    ###### iJobs中执行脚本成功和失败的标准只取决于脚本最后一条执行语句的返回值
    ###### 如果返回值为0，则认为此脚本执行成功，如果非0，则认为脚本执行失败
    
    main()


